package com.jc.repository.config;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.jc.repository.mapper.intercepor.MapperInterceptor;
import com.jc.repository.shard.database.PartitionDataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.annotation.Aspect;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author wangli
 * @create 2016-10-27 15:42
 * @description
 */

@Configuration
@Aspect
@EnableAspectJAutoProxy
@EnableTransactionManagement
@MapperScan("com.os.toytrade.mapper")
@ComponentScan(basePackages = {"com.jc", "com.os.toytrade"})
@Import(DataSourceProperties.class)
public class DaoConfig {

    private static Log log = LogFactory.getLog(DaoConfig.class);

    @Autowired
    DataSourceProperties dataSourceProperties;

    @Autowired
    MybatisProperties mybatisProperties;


    @Autowired
    private ResourceLoader resourceLoader = new DefaultResourceLoader();

//    @Bean(destroyMethod = "close")
    public ComboPooledDataSource abstractDataSource() {
        ComboPooledDataSource config = new ComboPooledDataSource();

        try {
            config.setDriverClass(dataSourceProperties.getDriverClass());
            config.setIdleConnectionTestPeriod(dataSourceProperties.getIdleConnectionTestPeriod());
            config.setPreferredTestQuery(dataSourceProperties.getPreferredTestQuery());
            config.setMaxIdleTime(dataSourceProperties.getMaxIdleTime());
            config.setInitialPoolSize(dataSourceProperties.getInitialPoolSize());
            config.setAcquireIncrement(dataSourceProperties.getAcquireIncrement());
            config.setAcquireRetryAttempts(dataSourceProperties.getAcquireRetryAttempts());

        } catch (Exception e) {
            e.printStackTrace();
            log.error("datasource init error", e);
        }

        return config;
    }

    @Bean
    public ComboPooledDataSource defaultDataSource() {

        ComboPooledDataSource config = abstractDataSource();

        config.setUser(dataSourceProperties.getUsername());
        config.setPassword(dataSourceProperties.getPassword());
        config.setJdbcUrl(dataSourceProperties.getUrl());
        config.setMaxPoolSize(dataSourceProperties.getMaxPoolSize());
        config.setMinPoolSize(dataSourceProperties.getMinPoolSize());

        return config;
    }

    @Bean
    public PartitionDataSource dataSource() {

        PartitionDataSource config = new PartitionDataSource();

        config.setTargetDataSources(ImmutableMap.<Object, Object>of("default", defaultDataSource()));
        config.setDefaultTargetDataSource(defaultDataSource());
        return config;
    }

    @Bean
    public DataSourceTransactionManager transactionManager() {
        DataSourceTransactionManager config = new DataSourceTransactionManager();
        config.setDataSource(dataSource());
        return config;
    }

    @Bean
    public JdbcTemplate jdbcTemplate() {
        JdbcTemplate config = new JdbcTemplate();
        config.setDataSource(dataSource());
        return config;
    }
    // mybaits 的bean

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory() throws Exception {


        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(dataSource());
//        if (StringUtils.hasText(mybatisProperties.getConfigLocation())) {
        factory.setConfigLocation(this.resourceLoader.getResource("classpath:sqlmap-config.xml"));
//        }

        String[] mapperLocations = {"classpath*:mapper/**/*.xml"};
        factory.setMapperLocations(resolveMapperLocations(mapperLocations));

        return factory;
//        return (SqlSessionFactoryBean) factory.getObject();
    }

    public Resource[] resolveMapperLocations(String[] mapperLocations) {
        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
        List<Resource> resources = new ArrayList<Resource>();
        for (String mapperLocation : mapperLocations) {
            try {
                Resource[] mappers = resourceResolver.getResources(mapperLocation);
                resources.addAll(Arrays.asList(mappers));
            } catch (IOException e) {
                // ignore
            }
        }
        return resources.toArray(new Resource[resources.size()]);
    }

    @Bean
    public MapperInterceptor mapperInterceptor() {
        MapperInterceptor config = new MapperInterceptor();
        return config;
    }


}
